package com.cloud.system.api.service.impl;

import com.cloud.system.api.bean.ByteFile;
import com.cloud.system.api.bean.NoticeBean;
import com.cloud.system.api.bean.NoticeCriteriaBean;
import com.cloud.system.api.entity.*;
import com.cloud.system.api.mapper.*;
import com.cloud.system.api.service.NoticeService;
import com.cloud.system.api.service.SystemCacheService;
import com.cloud.system.api.service.UnitInfoService;
import com.cloud.system.common.result.SelectItem;
import com.cloud.system.common.utils.SessionHelper;
import com.cloud.system.interfaces.FeignClientMedia;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private RoleInfoMapper roleInfoMapper;

    @Autowired
    private NoticeSendRoleMapper noticeSendRoleMapper;

    @Autowired
    private NoticeReadHumanMapper noticeReadHumanMapper;

    @Autowired
    private UnitInfoService unitInfoService;

    @Autowired
    private FeignClientMedia feignClientMedia;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SystemCacheService systemCacheService;

    @Override
    public PageInfo<NoticeBean> loadReceiveList(NoticeCriteriaBean noticeCriteriaBean) {
        Long id;
        if (SessionHelper.get().getHumanId() != -1) {
            List<Long> ids = roleInfoMapper.loafRoleIds(SessionHelper.get().getHumanId());
            id = ids.get(0);
        } else {
            id = new Long((long) 1501);
        }
        noticeCriteriaBean.setRoleId(id);
        PageInfo<NoticeBean> page = PageHelper.startPage(noticeCriteriaBean.getPageNum(), noticeCriteriaBean.getPageSize())
                .doSelectPageInfo(() -> {
                    noticeMapper.loadReceiveList(noticeCriteriaBean);
                });
        return page;
    }

    @Override
    public PageInfo<Notice> loadPublishList(NoticeCriteriaBean noticeCriteriaBean) {
        PageInfo<Notice> page = PageHelper.startPage(noticeCriteriaBean.getPageNum(), noticeCriteriaBean.getPageSize())
                .doSelectPageInfo(() -> {
                    noticeMapper.loadPublishList(noticeCriteriaBean);
                });
        return page;
    }

    @Override
    public List<SelectItem> loadRoleData(){
        return noticeMapper.loadRoleData();
    }

    @Override
    public NoticeBean save(NoticeBean noticeBean){
        if (noticeBean.getNoticeId() < 1) {
            noticeBean.setCreateHumanId(SessionHelper.get().getHumanId());
            noticeBean.setCreateHuman(SessionHelper.get().getHumanName());
            noticeBean.setCreateTime(new Date());
            noticeMapper.insertNotice(noticeBean);
        } else {
            Notice notice = noticeMapper.selectByPrimaryKey(noticeBean.getNoticeId());
            noticeBean.setCreateHumanId(notice.getCreateHumanId());
            noticeBean.setCreateHuman(notice.getCreateHuman());
            noticeBean.setCreateTime(notice.getCreateTime());
            BeanUtils.copyProperties(noticeBean,notice);
            noticeMapper.updateByPrimaryKey(notice);
        }
        noticeSendRoleMapper.deleteByNoticeId(noticeBean.getNoticeId());
        NoticeSendRole noticeSendRole = new NoticeSendRole();
        List<Integer> list = noticeBean.getRoles();
        for(int i = 0; i< list.size(); i++) {
            noticeSendRole.setNoticeId(noticeBean.getNoticeId());
            noticeSendRole.setRoleId(list.get(i));
            noticeSendRoleMapper.insert(noticeSendRole);
        }
        return noticeBean;
    }

    @Override
    public int deleteNoticeById(int noticeId) {
        noticeMapper.deleteByPrimaryKey(noticeId);
        noticeSendRoleMapper.deleteByNoticeId(noticeId);
        noticeReadHumanMapper.deleteByNoticeId(noticeId);
        return noticeId;
    }

    @Override
    public List<Notice> loadNotice() {
        Long id;
        if (SessionHelper.get().getHumanId() != -1) {
            List<Long> ids = roleInfoMapper.loafRoleIds(SessionHelper.get().getHumanId());
            id = ids.get(0);
        } else {
            id = new Long((long)1501);
        }
        return noticeMapper.loadNotice(id);
    }

    @Override
    public int haveRead(int noticeId) {
        NoticeReadHuman noticeReadHuman = new NoticeReadHuman();
        noticeReadHuman.setHumanId(SessionHelper.get().getHumanId());
        noticeReadHuman.setNoticeId(noticeId);
        int existNum = noticeReadHumanMapper.selectNumById(noticeReadHuman.getHumanId(),noticeId);
        if (existNum < 1) {
            noticeReadHuman.setReadTime(new Date());
            noticeReadHumanMapper.insert(noticeReadHuman);
        }
        return noticeId;
    }

    @Override
    public void autoSendNotice() throws IOException {
        NoticeBean noticeBean = new NoticeBean();
        NoticeSendRole noticeSendRole = new NoticeSendRole();
        byte[] testFile = unitInfoService.exportExcelForByte(new DynamicUnitExcel(),true);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String title = "执法监督数据汇总" + sdf.format(new Date()), content = "<p>请下载附件查看。</p>";
        List<byte[]> list = new ArrayList<>();
        list.add(testFile);
        ByteFile byteFile = new ByteFile();
        byteFile.setList(list);
        Media media = feignClientMedia.autoUpload(byteFile);
        Notice notice = new Notice(title, content, new Date(), "系统管理员", new Long(-1), "系统管理员", 1, media.getMediaId() + "" , media.getMediaName());
        BeanUtils.copyProperties(notice, noticeBean);
        noticeMapper.insertNotice(noticeBean);
        // 通知角色
        List<SelectItem> items = noticeMapper.loadRoleData();
        for(int i = 0; i< items.size(); i++) {
            noticeSendRole.setNoticeId(noticeBean.getNoticeId());
            noticeSendRole.setRoleId((Integer)items.get(i).getValue());
            noticeSendRoleMapper.insert(noticeSendRole);
        }
    }

    @Override
    public NoticeBean loadNoticeById(int noticeId) {
        NoticeBean noticeBean = new NoticeBean();
        Notice notice = noticeMapper.selectByPrimaryKey(noticeId);
        BeanUtils.copyProperties(notice, noticeBean);
        List<NoticeSendRole> roleList = jdbcTemplate.query("select role_id from notice_send_role where notice_id = " + noticeId, new BeanPropertyRowMapper<NoticeSendRole>(NoticeSendRole.class));
        List<Integer> list = new ArrayList<>();
        for (NoticeSendRole noticeSendRole: roleList) {
            list.add(noticeSendRole.getRoleId());
        }
        noticeBean.setRoles(list);
        String url = systemCacheService.loadSysConfigItem("DEFAULT_MEDIA_WEB_PATH_CONFIG");
        noticeBean.setUrls(getUrl(noticeBean.getAttachmentIds(), url));
        return noticeBean;
    }

    private List<Map<String, Object>> getUrl(String ids, String url) {
        List<Map<String, Object>> informUrl = new ArrayList<>();
        if (StringUtils.isNotBlank(ids)) {
            String[] inform = ids.trim().split("/");
            List<Media> informList = feignClientMedia.getAllMediaByIds(Arrays.asList(inform));
            if (informList != null) {
                informList.forEach(j -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", j.getMediaName());
                    map.put("url", url + j.getMediaPath());
                    map.put("uid", j.getMediaId());
                    informUrl.add(map);
                });
            }
        }
        return informUrl;
    }
}
